package com.tool.payment.billparser;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import com.tool.payment.model.PayOrder;

/**
 * 微信账单解析
 * @author huff
 *
 */
public class WeixinBillParser {
	
	private static final Logger logger = org.slf4j.LoggerFactory.getLogger(WeixinBillParser.class);
	
	private static final String title = "交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,企业红包金额,微信退款单号,商户退款单号,退款金额,企业红包退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率";
//	private static final String totalTitle = "总交易单数,总交易额,总退款金额,总企业红包退款金额,手续费总金额";
	
	private static final Pattern titlePattern = Pattern.compile("(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?)$");
	private static final Pattern pattern = Pattern.compile("^`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?),`(.*?)$");
	
//	private static final Pattern totalTitlePattern = Pattern.compile("(.*?),(.*?),(.*?),(.*?),(.*?)$");
//	private static final Pattern totalPattern = Pattern.compile("^`(.*?),`(.*?),`(.*?),`(.*?),`(.*?)$");

	public static Map<String, PayOrder> parser(File file) throws IOException {
		Map<String, PayOrder> result = new HashMap<String, PayOrder>();
		List<String> list = readLines(file);
		// 对账文件过滤空值
		for (Iterator<String> it = list.iterator(); it.hasNext();) {
			if (StringUtils.isBlank(it.next())) {
				it.remove();
			}
		}
		
		// 校验标题行
		String titleRawData = list.remove(0);
		if (!titlePattern.matcher(titleRawData).find()) {
			logger.info("校验标题行不通过, rawdata[" + titleRawData + "], 期望值[" + title + "]");
			return null;
		}
		
		list.remove(list.size() - 1);
		list.remove(list.size() - 1);
		
		//解析
		PayOrder order = null;
		for (String rawData : list) {
			Matcher matcher = pattern.matcher(rawData);
			if (matcher.find()) {
//				String tradetime = matcher.group(1);// 交易时间
				
				String outtradeno = matcher.group(6);//微信订单号
				String payorderid = matcher.group(7);
				String status = matcher.group(10);//状态
				String money = matcher.group(13);//金额
				int type = PayOrder.TYPE_USERPAY;
				if(status.equals("REFUND")) { //退款
					outtradeno = matcher.group(15);//微信订单号
					payorderid = matcher.group(16);
					money = matcher.group(17);//金额
					status = matcher.group(20);//
					type = PayOrder.TYPE_REFUNDTOUSER;
				}
				order = new PayOrder(Long.valueOf(payorderid),
									type,
									outtradeno,
									new BigDecimal(money).multiply(new BigDecimal("100")).intValue(),
									status);
				result.put(payorderid, order);
			}
		}
		return result;
	}
	
	
	private static List<String> readLines(File file)  throws IOException {
		InputStream in = null;
        try {
        	if (file.exists()) {
                if (file.isDirectory()) {
                    throw new IOException("File '" + file + "' exists but is a directory");
                }
                if (file.canRead() == false) {
                    throw new IOException("File '" + file + "' cannot be read");
                }
            } else {
                throw new FileNotFoundException("File '" + file + "' does not exist");
            }
            in = new FileInputStream(file);
            final InputStreamReader ireader = new InputStreamReader(in, "UTF-8");
            final BufferedReader reader = new BufferedReader(ireader);
            final List<String> list = new ArrayList<String>();
            String line = reader.readLine();
            while (line != null) {
                list.add(line);
                line = reader.readLine();
            }
            return list;
        } finally {
            in.close();
        }
	}
}
